#!/usr/bin/env python3
"""
简单的WebSocket服务器 - 无需额外依赖
适用于新电脑快速启动
"""

import socket
import hashlib
import base64
import threading
import json
import time
from datetime import datetime

class SimpleWebSocketServer:
    def __init__(self, host='0.0.0.0', port=8080):
        self.host = host
        self.port = port
        self.clients = []
        self.running = False
        
    def start(self):
        """启动服务器"""
        self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        
        try:
            self.server.bind((self.host, self.port))
            self.server.listen(5)
            self.running = True
            
            print(f"🚀 WebSocket服务器启动成功!")
            print(f"📍 监听地址: {self.host}:{self.port}")
            print(f"🌐 本地访问: ws://localhost:{self.port}")
            print(f"📱 客户端连接地址: ws://172.20.0.88:{self.port}")
            print(f"⏰ 启动时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
            print("=" * 50)
            print("等待客户端连接...")
            
            while self.running:
                try:
                    client_socket, addr = self.server.accept()
                    print(f"🔗 新连接来自: {addr}")
                    
                    # 启动新线程处理客户端
                    client_thread = threading.Thread(
                        target=self.handle_client, 
                        args=(client_socket, addr)
                    )
                    client_thread.daemon = True
                    client_thread.start()
                    
                except Exception as e:
                    if self.running:
                        print(f"❌ 接受连接时出错: {e}")
                        
        except Exception as e:
            print(f"❌ 服务器启动失败: {e}")
        finally:
            self.stop()
            
    def stop(self):
        """停止服务器"""
        self.running = False
        if hasattr(self, 'server'):
            self.server.close()
        print("🛑 服务器已停止")
        
    def handle_client(self, client_socket, addr):
        """处理客户端连接"""
        try:
            # WebSocket握手
            request = client_socket.recv(1024).decode('utf-8')
            if 'Upgrade: websocket' in request:
                response = self.websocket_handshake(request)
                client_socket.send(response.encode('utf-8'))
                
                # 添加到客户端列表
                self.clients.append(client_socket)
                print(f"✅ WebSocket连接建立: {addr}")
                print(f"📊 当前连接数: {len(self.clients)}")
                
                # 发送欢迎消息
                welcome_msg = {
                    'type': 'SYSTEM',
                    'data': {
                        'message': 'WebSocket连接成功',
                        'timestamp': datetime.now().isoformat()
                    }
                }
                self.send_message(client_socket, json.dumps(welcome_msg))
                
                # 监听消息
                while self.running:
                    try:
                        message = self.receive_message(client_socket)
                        if message:
                            print(f"📨 收到消息: {message}")
                            self.handle_message(client_socket, message)
                        else:
                            break
                    except:
                        break
                        
        except Exception as e:
            print(f"❌ 处理客户端时出错: {e}")
        finally:
            if client_socket in self.clients:
                self.clients.remove(client_socket)
            client_socket.close()
            print(f"🔌 客户端断开: {addr}")
            print(f"📊 当前连接数: {len(self.clients)}")
            
    def websocket_handshake(self, request):
        """WebSocket握手"""
        key = None
        for line in request.split('\r\n'):
            if line.startswith('Sec-WebSocket-Key'):
                key = line.split(': ')[1]
                break
                
        if key:
            # 计算接受密钥
            magic_string = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
            accept_key = base64.b64encode(
                hashlib.sha1((key + magic_string).encode()).digest()
            ).decode()
            
            response = (
                "HTTP/1.1 101 Switching Protocols\r\n"
                "Upgrade: websocket\r\n"
                "Connection: Upgrade\r\n"
                f"Sec-WebSocket-Accept: {accept_key}\r\n\r\n"
            )
            return response
        return ""
        
    def send_message(self, client_socket, message):
        """发送消息到客户端"""
        try:
            message_bytes = message.encode('utf-8')
            length = len(message_bytes)
            
            if length < 126:
                frame = bytes([0x81, length]) + message_bytes
            elif length < 65536:
                frame = bytes([0x81, 126]) + length.to_bytes(2, 'big') + message_bytes
            else:
                frame = bytes([0x81, 127]) + length.to_bytes(8, 'big') + message_bytes
                
            client_socket.send(frame)
        except:
            pass
            
    def receive_message(self, client_socket):
        """接收客户端消息"""
        try:
            data = client_socket.recv(2)
            if len(data) < 2:
                return None
                
            opcode = data[0] & 0x0f
            masked = data[1] & 0x80
            length = data[1] & 0x7f
            
            if length == 126:
                length = int.from_bytes(client_socket.recv(2), 'big')
            elif length == 127:
                length = int.from_bytes(client_socket.recv(8), 'big')
                
            if masked:
                mask = client_socket.recv(4)
                message_bytes = client_socket.recv(length)
                message_bytes = bytes([b ^ mask[i % 4] for i, b in enumerate(message_bytes)])
            else:
                message_bytes = client_socket.recv(length)
                
            return message_bytes.decode('utf-8')
        except:
            return None
            
    def handle_message(self, client_socket, message):
        """处理收到的消息"""
        try:
            data = json.loads(message)
            msg_type = data.get('type', '')
            
            if msg_type == 'AUTH':
                print("🔐 收到认证消息")
                response = {
                    'type': 'AUTH_RESPONSE',
                    'data': {
                        'status': 'success',
                        'message': '认证成功',
                        'timestamp': datetime.now().isoformat()
                    }
                }
                self.send_message(client_socket, json.dumps(response))
                
            elif msg_type == 'HEARTBEAT':
                print("💓 收到心跳")
                response = {
                    'type': 'HEARTBEAT_RESPONSE',
                    'data': {
                        'timestamp': datetime.now().isoformat()
                    }
                }
                self.send_message(client_socket, json.dumps(response))
                
            elif msg_type == 'PATIENT_REPORT':
                print("🏥 收到患者上报")
                # 广播给所有客户端
                broadcast_msg = {
                    'type': 'PATIENT_REPORT_RESPONSE',
                    'data': data.get('data', {}),
                    'timestamp': datetime.now().isoformat()
                }
                self.broadcast_message(json.dumps(broadcast_msg))
                
            else:
                print(f"❓ 未知消息类型: {msg_type}")
                
        except Exception as e:
            print(f"❌ 处理消息出错: {e}")
            
    def broadcast_message(self, message):
        """广播消息给所有客户端"""
        disconnected = []
        for client in self.clients:
            try:
                self.send_message(client, message)
            except:
                disconnected.append(client)
                
        # 移除断开的客户端
        for client in disconnected:
            if client in self.clients:
                self.clients.remove(client)

if __name__ == "__main__":
    server = SimpleWebSocketServer()
    try:
        server.start()
    except KeyboardInterrupt:
        print("\n⏹️  服务器停止中...")
        server.stop() 